home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1999 / MacHack 1999.toast / The Hacks / X-Ray / X-Ray INIT Source / x_ray.c < prev    next >
Encoding:
Text File  |  1999-06-13  |  20.1 KB  |  735 lines  |  [TEXT/CWIE]

  1. // Copyright (C) 1999 Eric Roccasecca.  All rights reserved.
  2.  
  3. #include "X_Ray_Priv.h"
  4. #include "Layers.h"
  5.  
  6.  
  7. // Disposes of all memory allocated for a transparent or clear window
  8. OSErr X_Ray_DisposeWindow (X_Ray_WindowHandle deadWin)
  9. {
  10.     HLock ((Handle)deadWin);
  11.     
  12.     X_Ray_FixOwningListEnds (deadWin); // fix list head if necessary
  13.     
  14.     if ((*deadWin)->nextWindow)
  15.         (*((*deadWin)->nextWindow))->previousWindow = (*deadWin)->previousWindow;
  16.     if ((*deadWin)->previousWindow)
  17.         (*((*deadWin)->previousWindow))->nextWindow = (*deadWin)->nextWindow;
  18.     
  19.     // release allocated memory
  20.     DisposeGWorld ((*deadWin)->underBuffer);
  21.     DisposeGWorld ((*deadWin)->contentBuffer);
  22.     DisposeGWorld ((*deadWin)->mixBuffer);
  23.     DisposeGWorld ((*deadWin)->maskBuffer);
  24.     DisposeRgn ((*deadWin)->transparentUpdateRgn);
  25.     
  26.     HUnlock ((Handle)deadWin);
  27.     
  28.     DisposeHandle ((Handle)deadWin);
  29. }
  30.  
  31.  
  32. // fixes the list ends if the window is the at an end of the list
  33. void X_Ray_FixOwningListEnds (X_Ray_WindowHandle theWindow)
  34. {
  35.     if (((*theWindow)->windowKind)&kTSMWindow)
  36.     {
  37.         if (theWindow == gCommRec.tsmWindowList)
  38.             gCommRec.tsmWindowList = (*theWindow)->nextWindow;
  39.         if (theWindow == gCommRec.tsmLastWindow)
  40.             gCommRec.tsmLastWindow = (*theWindow)->previousWindow;
  41.     }
  42.     else
  43.     {
  44.         if (theWindow == (*((*theWindow)->owner))->windowList)
  45.             (*((*theWindow)->owner))->windowList = (*theWindow)->nextWindow;
  46.         if (theWindow == (*((*theWindow)->owner))->lastWindow)
  47.             (*((*theWindow)->owner))->lastWindow = (*theWindow)->previousWindow;
  48.     }
  49. }
  50.  
  51.  
  52. // retrieves the transparent window record associated with a specific window
  53. // will not return a window record for a trans window that has been marked as disposed
  54. X_Ray_WindowHandle X_Ray_GetWindowRec (WindowPtr theWindow)
  55. {
  56.     X_Ray_AppRecHandle        curApp;
  57.     X_Ray_WindowHandle        curTransWindow = nil;
  58.     
  59.     if (theWindow == nil)
  60.         return nil;
  61.     
  62.     // first, check tsm window list
  63.     curTransWindow = gCommRec.tsmWindowList;
  64.     while (curTransWindow)
  65.     {
  66.         if ((*curTransWindow)->theWindow == theWindow)
  67.         {
  68.             // found the window, but is it marked and disposed
  69.             return curTransWindow;
  70.         }
  71.         
  72.         curTransWindow = (*curTransWindow)->nextWindow;
  73.     }
  74.     
  75.     // second, check application window list
  76.     curApp = gCommRec.appList;
  77.     while (curApp)
  78.     {
  79.         curTransWindow = (*curApp)->windowList;
  80.         while (curTransWindow) // scan the transparent window list
  81.         {
  82.             if ((*curTransWindow)->theWindow == theWindow)
  83.             {
  84.                 // found the window, but is it marked and disposed
  85.                 return curTransWindow;
  86.             }
  87.             curTransWindow = (*curTransWindow)->nextWindow;
  88.         }
  89.         curApp = (*curApp)->nextApp;
  90.     }
  91.     
  92.     return nil;
  93. }
  94.  
  95.  
  96. // returns a particular feature for a transparent or clear window
  97. long X_Ray_GetWindowFeature (WindowPtr theWindow, short kFeatureKind)
  98. {
  99.     X_Ray_WindowHandle        curWin;
  100.     long                    result = 0;
  101.     
  102.     curWin = X_Ray_GetWindowRec (theWindow);
  103.     if (curWin)
  104.     {
  105.         switch (kFeatureKind)
  106.         {
  107.             case kTransWindowUnderBuffer:
  108.                 result = (long)(*curWin)->underBuffer;
  109.                 break;
  110.             case kTransWindowContentBuffer:
  111.                 result = (long)(*curWin)->contentBuffer;
  112.                 break;
  113.             case kTransWindowMixBuffer:
  114.                 result = (long)(*curWin)->mixBuffer;
  115.                 break;
  116.             case kTransWindowTransparency:
  117.                 result = (long)(*curWin)->transparency;
  118.                 break;
  119.             case kTransWindowOwner:
  120.                 result = (long)&(*curWin)->owner;
  121.                 break;
  122.             case kX_RayWindowKind:
  123.                 result = (*curWin)->windowKind;
  124.                 break;
  125.             case kClearWindowClearColor:
  126.                 result = (long)&(*curWin)->clearColor;
  127.                 break;
  128.             case kTransWindowStandardWDEF:
  129.                 result = (long)(*curWin)->origWDEF;
  130.                 break;
  131.             default:
  132.                 break;
  133.         }
  134.     }
  135.     
  136.     return result;
  137. }
  138.  
  139.  
  140. // globals used by the function PortIsOnScreen
  141. GrafPtr        gLastPortCheckedAsWindow = nil;
  142. Boolean        gLastPortCheckedWasWindow = false;
  143.  
  144. // see if a port is a window
  145. // compare its base address to any screen device
  146. // is there a better way to do this?
  147. Boolean PortIsOnScreen (GrafPtr thePort)
  148. {
  149.     GDHandle    curDevice;
  150.     
  151.     if (gLastPortCheckedAsWindow == thePort)
  152.         return gLastPortCheckedWasWindow;
  153.     
  154.     gLastPortCheckedAsWindow = thePort;
  155.     gLastPortCheckedWasWindow = false;
  156.     
  157.     curDevice = GetDeviceList();
  158.     while (curDevice)
  159.     {
  160.         if ((*curDevice)->gdFlags&(1<<screenDevice))  // only check devices that are screens
  161.         {
  162.             if (((CGrafPtr)thePort)->portVersion&0xC000) // is color port
  163.             {
  164.                 if (GetPixBaseAddr((*curDevice)->gdPMap) == GetPixBaseAddr(((CGrafPtr)thePort)->portPixMap))
  165.                 {
  166.                     gLastPortCheckedWasWindow = true;
  167.                     return gLastPortCheckedWasWindow;
  168.                 }
  169.             }
  170.             else // is BW port
  171.             {
  172.                 if (GetPixBaseAddr((*curDevice)->gdPMap) == thePort->portBits.baseAddr)
  173.                 {
  174.                     gLastPortCheckedWasWindow = true;
  175.                     return gLastPortCheckedWasWindow;
  176.                 }
  177.             }
  178.         }
  179.         curDevice = (GDHandle)(*curDevice)->gdNextGD;
  180.     }
  181.     
  182.     return gLastPortCheckedWasWindow;
  183. }
  184.  
  185.  
  186. // see if a BitMap/PixMap is on screen
  187. // compare its base address to any screen device
  188. Boolean BitMapIsOnScreen (const BitMap *theBMap)
  189. {
  190.     GDHandle    curDevice;
  191.     Boolean        isScreen = false;
  192.     
  193.     curDevice = GetDeviceList();
  194.     while (curDevice)
  195.     {
  196.         if ((*curDevice)->gdFlags&(1<<screenDevice))  // only check devices that are screens
  197.         {
  198.             if ((theBMap->rowBytes)&0xC000) // is color port
  199.             {
  200.                 if (GetPixBaseAddr((*curDevice)->gdPMap) == theBMap->baseAddr) // even though theBMap is color, because this is a comparison to a screen this appears to be legal
  201.                 {
  202.                     isScreen = true;
  203.                     return isScreen;
  204.                 }
  205.             }
  206.             else // is BW port
  207.             {
  208.                 if (GetPixBaseAddr((*curDevice)->gdPMap) == theBMap->baseAddr)
  209.                 {
  210.                     isScreen = true;
  211.                     return isScreen;
  212.                 }
  213.             }
  214.         }
  215.         curDevice = (GDHandle)(*curDevice)->gdNextGD;
  216.     }
  217.     
  218.     return isScreen;
  219. }
  220.  
  221.  
  222. // globals used by the function PortDoesIntersect
  223. X_Ray_WindowHandle        gLastPortIntersection = nil;
  224. RgnHandle                gIntersectCurPortVisRgn, gIntersectCurTransVisRgn; // intialized in qdPatches.c
  225.  
  226. // determines if a port is on screen (by calling PortIsOnScreen) and if it
  227. // intersects at least one transparent window and intersects the current drawRgn
  228. // returns back-most transparent window intersected
  229. X_Ray_WindowHandle PortDoesIntersect (GrafPtr thePort, RgnHandle drawRgn)
  230. {
  231.     X_Ray_WindowHandle        curTransWindow;
  232.     X_Ray_AppRecHandle        curApp;
  233.     GrafPtr                    curPort;
  234.     
  235.     if (thePort == nil) // just to be safe
  236.         return nil;
  237.     
  238.     // not on screen so there are no intersections possible
  239.     if (!PortIsOnScreen (thePort))
  240.         return nil;
  241.     
  242.     GetPort (&curPort);
  243.     
  244.     gLastPortIntersection = nil;
  245.     
  246.     CopyRgn (thePort->visRgn, gIntersectCurPortVisRgn);
  247.     X_Ray_LocalToGlobalRgn (gIntersectCurPortVisRgn);
  248.     
  249.     // examine transparent TSM window list
  250.     curTransWindow = gCommRec.tsmWindowList;
  251.     while (curTransWindow)
  252.     {
  253.         SetPort ((*curTransWindow)->theWindow);
  254.         CopyRgn (((*curTransWindow)->theWindow)->visRgn, gIntersectCurTransVisRgn);
  255.         X_Ray_LocalToGlobalRgn (gIntersectCurTransVisRgn);
  256.         SectRgn (gIntersectCurPortVisRgn, gIntersectCurTransVisRgn, gIntersectCurTransVisRgn);
  257.         SectRgn (drawRgn, gIntersectCurTransVisRgn, gIntersectCurTransVisRgn);
  258.         if (!EmptyRgn (gIntersectCurTransVisRgn))
  259.             gLastPortIntersection = curTransWindow;
  260.         curTransWindow = (*curTransWindow)->nextWindow;
  261.     }
  262.     
  263.     // examine application transparent window lists
  264.     curApp = gCommRec.appList;
  265.     while (curApp)
  266.     {
  267.         curTransWindow = (*curApp)->windowList;
  268.         while (curTransWindow)
  269.         {
  270.             SetPort ((*curTransWindow)->theWindow);
  271.             CopyRgn (((*curTransWindow)->theWindow)->visRgn, gIntersectCurTransVisRgn);
  272.             X_Ray_LocalToGlobalRgn (gIntersectCurTransVisRgn);
  273.             SectRgn (gIntersectCurPortVisRgn, gIntersectCurTransVisRgn, gIntersectCurTransVisRgn);
  274.             SectRgn (drawRgn, gIntersectCurTransVisRgn, gIntersectCurTransVisRgn);
  275.             if (!EmptyRgn (gIntersectCurTransVisRgn))
  276.                 gLastPortIntersection = curTransWindow;
  277.             curTransWindow = (*curTransWindow)->nextWindow;
  278.         }
  279.         curApp = (*curApp)->nextApp;
  280.     }
  281.     
  282.     SetPort (curPort);
  283.     
  284.     return gLastPortIntersection;
  285. }
  286.  
  287.  
  288. // reorders an app's transparent window list
  289. void ReorderWindow (X_Ray_WindowHandle theWindow, short reorderMethod, WindowPtr switchWindow)
  290. {
  291.     WindowPtr                curWindow;
  292.     X_Ray_WindowHandle        curTransWindow, lastTransWindow;
  293.     X_Ray_AppRecHandle        curApp;
  294.     
  295.     if ((*theWindow)->windowKind&kTSMWindow)
  296.     {
  297.         curTransWindow = gCommRec.tsmWindowList;
  298.         GetFrontServiceWindow (&curWindow); // get front TSM window
  299.     }
  300.     else
  301.     {
  302.         curApp = (*theWindow)->owner;
  303.         curTransWindow = (*((*theWindow)->owner))->windowList;
  304.         curWindow = GetFirstLayerWindow ((LayerPtr)(*curApp)->appGlobalWindow);    // get front of window list of owner app
  305.     }
  306.     
  307.     switch (reorderMethod) {
  308.         // these methods bring the window to front
  309.         case kROMethod_MoveWindow:
  310.         case kROMethod_BringToFront:
  311.         case kROMethod_SelectWindow:
  312.         case kROMethod_DragWindow:
  313.             if (theWindow == curTransWindow) // window is already front most
  314.                 break;
  315.             
  316.             if ((*theWindow)->nextWindow)
  317.                 (*(*theWindow)->nextWindow)->previousWindow = (*theWindow)->previousWindow;
  318.             if ((*theWindow)->previousWindow)
  319.                 (*(*theWindow)->previousWindow)->nextWindow = (*theWindow)->nextWindow;
  320.             
  321.             if ((*theWindow)->windowKind&kTSMWindow) // TSM
  322.             {
  323.                 if ((gCommRec.tsmLastWindow == theWindow) && (*theWindow)->previousWindow) // fix end of list
  324.                     gCommRec.tsmLastWindow = (*theWindow)->previousWindow;
  325.                 (*theWindow)->nextWindow = gCommRec.tsmWindowList;
  326.                 gCommRec.tsmWindowList = theWindow;
  327.             }
  328.             else // app window
  329.             {
  330.                 if (((*((*theWindow)->owner))->lastWindow == theWindow) && (*theWindow)->previousWindow) // fix end of list
  331.                     (*((*theWindow)->owner))->lastWindow = (*theWindow)->previousWindow;
  332.                 (*theWindow)->nextWindow = (*((*theWindow)->owner))->windowList;
  333.                 (*((*theWindow)->owner))->windowList = theWindow;
  334.             }
  335.             
  336.             (*theWindow)->previousWindow = nil;
  337.             (*(*theWindow)->nextWindow)->previousWindow = theWindow;
  338.             break;
  339.         
  340.         // these methods move a window in the window list
  341.         case kROMethod_HideWindow:
  342.         case kROMethod_ShowHide:
  343.         case kROMethod_SendBehind:
  344.             if (switchWindow == (*theWindow)->theWindow) // no need to move a window behind itself
  345.                 break;
  346.             
  347.             // moving to end of window list
  348.             if ((switchWindow == nil) || (switchWindow && ((WindowPeek)switchWindow)->nextWindow == nil))
  349.             {
  350.                 if ((*theWindow)->nextWindow)
  351.                 {
  352.                     if ((*theWindow)->windowKind&kTSMWindow)
  353.                     {
  354.                         // fix list head
  355.                         if (gCommRec.tsmWindowList == theWindow)
  356.                             gCommRec.tsmWindowList = (*theWindow)->nextWindow;
  357.                     }
  358.                     else
  359.                     {
  360.                         // fix list head
  361.                         if ((*((*theWindow)->owner))->windowList == theWindow)
  362.                             (*((*theWindow)->owner))->windowList = (*theWindow)->nextWindow;
  363.                     }
  364.                     
  365.                     (*(*theWindow)->nextWindow)->previousWindow = (*theWindow)->previousWindow;
  366.                     
  367.                     // only update the previous window if there really is a next window
  368.                     if ((*theWindow)->previousWindow)
  369.                         (*(*theWindow)->previousWindow)->nextWindow = (*theWindow)->nextWindow;
  370.                 }
  371.                             
  372.                 if ((*theWindow)->windowKind&kTSMWindow)
  373.                 {
  374.                     // fix list end
  375.                     if (gCommRec.tsmLastWindow != theWindow)
  376.                     {
  377.                         (*gCommRec.tsmLastWindow)->nextWindow = theWindow;
  378.                         (*theWindow)->previousWindow = gCommRec.tsmLastWindow;
  379.                         gCommRec.tsmLastWindow = theWindow;
  380.                     }
  381.                 }
  382.                 else 
  383.                 {
  384.                     // fix list end
  385.                     if ((*((*theWindow)->owner))->lastWindow != theWindow)
  386.                     {
  387.                         (*(*((*theWindow)->owner))->lastWindow)->nextWindow = theWindow;
  388.                         (*theWindow)->previousWindow = (*((*theWindow)->owner))->lastWindow;
  389.                         (*((*theWindow)->owner))->lastWindow = theWindow;
  390.                     }
  391.                 }
  392.                 
  393.                 (*theWindow)->nextWindow = nil;
  394.             }
  395.             else // moving within the list
  396.             {
  397.                 while (curWindow)
  398.                 {
  399.                     if (curTransWindow) // keep track of last transwin found
  400.                         lastTransWindow = curTransWindow;
  401.                     curTransWindow = X_Ray_GetWindowRec (curWindow);
  402.                     if (curWindow == switchWindow)
  403.                     {
  404.                         if (curTransWindow == nil)
  405.                             curTransWindow = lastTransWindow;
  406.                         if ((curTransWindow != theWindow) && ((*curTransWindow)->nextWindow != theWindow)) // no need to move if already there
  407.                         {
  408.                             if ((*theWindow)->nextWindow)
  409.                             {
  410.                                 // fix list head
  411.                                 if ((*theWindow)->windowKind&kTSMWindow)
  412.                                 {
  413.                                     if (gCommRec.tsmWindowList == theWindow)
  414.                                         gCommRec.tsmWindowList = (*theWindow)->nextWindow;
  415.                                 }
  416.                                 else
  417.                                 {
  418.                                     if ((*((*theWindow)->owner))->windowList == theWindow)
  419.                                         (*((*theWindow)->owner))->windowList = (*theWindow)->nextWindow;
  420.                                 }
  421.                                 
  422.                                 (*(*theWindow)->nextWindow)->previousWindow = (*theWindow)->previousWindow;
  423.                             }
  424.                                                         
  425.                             if ((*theWindow)->previousWindow)
  426.                                 (*(*theWindow)->previousWindow)->nextWindow = (*theWindow)->nextWindow;
  427.                             
  428.                             (*theWindow)->nextWindow = (*curTransWindow)->nextWindow;
  429.                             (*theWindow)->previousWindow = curTransWindow;
  430.                             
  431.                             if ((*curTransWindow)->nextWindow)
  432.                                 (*(*curTransWindow)->nextWindow)->previousWindow = theWindow;
  433.                             
  434.                             (*curTransWindow)->nextWindow = theWindow;
  435.                             
  436.                             // fix end of list
  437.                             if ((*theWindow)->nextWindow == nil)
  438.                             {
  439.                                 if ((*theWindow)->windowKind&kTSMWindow)
  440.                                     gCommRec.tsmLastWindow = theWindow;
  441.                                 else
  442.                                     (*((*theWindow)->owner))->lastWindow = theWindow;
  443.                             }
  444.                         }
  445.                         
  446.                         break;
  447.                     }
  448.                     
  449.                     curWindow = (WindowPtr)((WindowPeek)curWindow)->nextWindow;
  450.                 }
  451.             }
  452.             break;
  453.         
  454.         default:
  455.             break;
  456.     }
  457. }
  458.  
  459.  
  460. // if a WindowPtr happens to be the global window for an application return the app record
  461. X_Ray_AppRecHandle WindowIsGlobalAppWindow (WindowPtr theWindow)
  462. {
  463.     X_Ray_AppRecHandle        curApp;
  464.     
  465.     curApp = gCommRec.appList;
  466.     while (curApp)
  467.     {
  468.         if (theWindow == (WindowPtr)(*curApp)->appGlobalWindow)
  469.             return curApp;
  470.         curApp = (*curApp)->nextApp;
  471.     }
  472.     
  473.     return nil;
  474. }
  475.  
  476.  
  477. // makes sure that a normal window's old location is refreshed properly when the window is moved
  478. // and it intersected transparent windows behind it at its old location
  479. // this fixes underlying window frames that do not redraw correctly
  480. void AssureOldWindowLocationIsRefreshed (WindowPtr theWindow, RgnHandle oldStrucRgn)
  481. {
  482.     RgnHandle    cur_intersectRgn;
  483.     Boolean        doRefresh = false;
  484.     GrafPtr        origPort;
  485.     WindowPtr    nextWind;
  486.     
  487.     if (!IsWindowTransparent(theWindow))
  488.     {
  489.         GetPort (&origPort);
  490.         cur_intersectRgn = NewRgn();
  491.         
  492.         nextWind = (WindowPtr)((WindowPeek)theWindow)->nextWindow;
  493.         while (nextWind && !doRefresh)
  494.         {
  495.             if (IsWindowTransparent(nextWind))
  496.             {
  497.                 SectRgn (oldStrucRgn, ((WindowPeek)nextWind)->contRgn, cur_intersectRgn);
  498.                 if (!EmptyRgn (cur_intersectRgn))
  499.                     doRefresh = true; // found an intersection, redraw
  500.             }
  501.             
  502.             nextWind = (WindowPtr)((WindowPeek)nextWind)->nextWindow;
  503.         }
  504.         
  505.         if (doRefresh)
  506.             PaintBehind (theWindow, oldStrucRgn);
  507.         
  508.         DisposeRgn (cur_intersectRgn);
  509.     }
  510. }
  511.  
  512.  
  513. // makes sure that normal windows get refreshed properly when brought in front of
  514. // transparent windows in the same layer
  515. void AssureMovingWindowIsRefreshed (WindowPtr theWindow)
  516. {
  517.     RgnHandle    cur_visRgn, cur_intersectRgn,
  518.                 accumulated_VisUpdateRgn, accumulated_StrucUpdateRgn;
  519.     GrafPtr        origPort;
  520.     WindowPtr    nextWind;
  521.     
  522.     if (!IsWindowTransparent(theWindow))
  523.     {
  524.         GetPort (&origPort);
  525.         
  526.         cur_visRgn = NewRgn();
  527.         cur_intersectRgn = NewRgn();
  528.         accumulated_VisUpdateRgn = NewRgn();
  529.         accumulated_StrucUpdateRgn = NewRgn();
  530.         
  531.         SetPort (theWindow);
  532.         CopyRgn (theWindow->visRgn, cur_visRgn);
  533.         X_Ray_LocalToGlobalRgn (cur_visRgn);
  534.         
  535.         nextWind = (WindowPtr)((WindowPeek)theWindow)->nextWindow;
  536.         while (nextWind)
  537.         {
  538.             if (IsWindowTransparent(nextWind))
  539.             {
  540.                 // accumulate the vis rgn intersections
  541.                 SectRgn (cur_visRgn, ((WindowPeek)nextWind)->contRgn, cur_intersectRgn);
  542.                 if (!EmptyRgn (cur_intersectRgn))
  543.                     UnionRgn (cur_intersectRgn, accumulated_VisUpdateRgn, accumulated_VisUpdateRgn);
  544.                 
  545.                 // accumulate normal struc rgn - transparent contRgn intersections
  546.                 SectRgn (((WindowPeek)theWindow)->strucRgn, ((WindowPeek)nextWind)->contRgn, cur_intersectRgn);
  547.                 if (!EmptyRgn (cur_intersectRgn))
  548.                     UnionRgn (cur_intersectRgn, accumulated_StrucUpdateRgn, accumulated_StrucUpdateRgn);
  549.             }
  550.             
  551.             nextWind = (WindowPtr)((WindowPeek)nextWind)->nextWindow;
  552.         }
  553.         
  554.         if (!EmptyRgn (accumulated_VisUpdateRgn))
  555.         {
  556.             SetPort (theWindow);
  557.             X_Ray_GlobalToLocalRgn (accumulated_VisUpdateRgn);
  558.             InvalRgn (accumulated_VisUpdateRgn);
  559.         }
  560.         
  561.         if (!EmptyRgn (accumulated_StrucUpdateRgn))
  562.             PaintBehind (theWindow, accumulated_StrucUpdateRgn);
  563.         
  564.         DisposeRgn (cur_visRgn);
  565.         DisposeRgn (cur_intersectRgn);
  566.         DisposeRgn (accumulated_VisUpdateRgn);
  567.         DisposeRgn (accumulated_StrucUpdateRgn);
  568.         
  569.         SetPort (origPort);
  570.     }
  571. }
  572.  
  573.  
  574. // returns the next standard Mac OS window behind theWindow
  575. // if theWindow is nil, the front most window of all layers is returned
  576. // the returned window may be in any layer
  577. // *curApp is a reference to the current layer that owns theWindow
  578. // if *curApp is nil upon exit and theWindow is not nil, then theWindow is a TSM window
  579. WindowPtr GetNextNormalWindow (WindowPtr theWindow, X_Ray_AppRecHandle *curApp)
  580. {
  581.     if (curApp == nil)
  582.         return nil;
  583.     
  584.     if (theWindow == nil)
  585.     {
  586.         *curApp = nil;
  587.         GetFrontServiceWindow (&theWindow);
  588.         
  589.         if (theWindow == nil)
  590.         {
  591.             *curApp = gCommRec.appList;
  592.             while (*curApp)
  593.             {
  594.                 theWindow = GetFirstLayerWindow ((LayerPtr)(*(*curApp))->appGlobalWindow);
  595.                 if (theWindow == nil)
  596.                     *curApp = (*(*curApp))->nextApp;
  597.                 else
  598.                     break;
  599.             }
  600.         }
  601.     }
  602.     else
  603.     {
  604.         theWindow = (WindowPtr)((WindowPeek)theWindow)->nextWindow;
  605.         if (theWindow == nil)
  606.         {
  607.             if (*curApp == nil)
  608.                 *curApp = gCommRec.appList;
  609.             else
  610.                 *curApp = (*(*curApp))->nextApp;
  611.             
  612.             while (*curApp)
  613.             {
  614.                 theWindow = GetFirstLayerWindow ((LayerPtr)(*(*curApp))->appGlobalWindow);
  615.                 if (theWindow == nil)
  616.                     *curApp = (*(*curApp))->nextApp;
  617.                 else
  618.                     break;
  619.             }
  620.         }
  621.     }
  622.     
  623.     return theWindow;
  624. }
  625.  
  626. // returns the transwin in front of theWindow
  627. // if theWindow is nil, the back most transwin is returned
  628. // the returned transwin may be in any layer
  629. X_Ray_WindowHandle GetNextWindowAbove (X_Ray_WindowHandle theWindow)
  630. {
  631.     X_Ray_WindowHandle    tempWin;
  632.     X_Ray_AppRecHandle    curApp;
  633.     
  634.     // passed in nil so return the back most transparent window
  635.     if (theWindow == nil)
  636.     {
  637.         curApp = gCommRec.appList;
  638.         while ((*curApp)->nextApp) // walk to end of app list
  639.             curApp = (*curApp)->nextApp;
  640.         
  641.         while (curApp && (theWindow == nil))
  642.         {
  643.             theWindow = (*curApp)->lastWindow;
  644.             curApp = (*curApp)->previousApp;
  645.         }
  646.         
  647.         if (theWindow == nil)
  648.             theWindow = gCommRec.tsmLastWindow;
  649.     }
  650.     else
  651.     {
  652.         tempWin = theWindow;
  653.         theWindow = (*theWindow)->previousWindow; // move forward through the list
  654.         if (theWindow == nil) // ran out of transWins, look for them in other apps or in the TSM window list
  655.         {
  656.             if (!((*tempWin)->windowKind&kTSMWindow)) // current trans window isn't a TSM window
  657.             {
  658.                 curApp = (*(*tempWin)->owner)->previousApp;
  659.                 while (curApp && (theWindow == nil))
  660.                 {
  661.                     theWindow = (*curApp)->lastWindow;
  662.                     curApp = (*curApp)->previousApp;
  663.                 }
  664.                 // even after searching all the app lists, theWindow is still nil
  665.                 // so try looking at the tsmWindowList
  666.                 if (theWindow == nil)
  667.                     theWindow = gCommRec.tsmLastWindow;
  668.             }
  669.         }
  670.     }
  671.     
  672.     return theWindow;
  673. }
  674.  
  675. // returns the next transwin behind theWindow
  676. // if theWindow is nil, the front most transwin is returned
  677. // the returned transwin may be in any layer
  678. X_Ray_WindowHandle GetNextWindowBehind (X_Ray_WindowHandle theWindow)
  679. {
  680.     X_Ray_WindowHandle    tempWin;
  681.     X_Ray_AppRecHandle    curApp;
  682.     
  683.     // passed in nil so return the front most transparent window
  684.     if (theWindow == nil)
  685.     {
  686.         theWindow = gCommRec.tsmWindowList;
  687.         if (theWindow == nil)
  688.         {
  689.             curApp = gCommRec.appList;
  690.             while (curApp && (theWindow == nil))
  691.             {
  692.                 theWindow = (*curApp)->windowList;
  693.                 curApp = (*curApp)->nextApp;
  694.             }
  695.         }
  696.     }
  697.     else
  698.     {
  699.         tempWin = theWindow;
  700.         theWindow = (*theWindow)->nextWindow; // move back through the list
  701.         if (theWindow == nil) // ran out of transWins, look for them in other apps or in the TSM window list
  702.         {
  703.             if (((*tempWin)->windowKind&kTSMWindow)) // current trans window is a TSM window
  704.                 curApp = gCommRec.appList;
  705.             else
  706.                 curApp = (*(*tempWin)->owner)->nextApp;
  707.             
  708.             while (curApp && (theWindow == nil))
  709.             {
  710.                 theWindow = (*curApp)->windowList;
  711.                 curApp = (*curApp)->nextApp;
  712.             }
  713.         }
  714.     }
  715.     
  716.     return theWindow;
  717. }
  718.  
  719.  
  720. void DumpTransparentWindowList (void)
  721. {
  722.     X_Ray_WindowHandle    theWindow = nil;
  723.     
  724.     DebugStr ("\p-- START OF LIST --;g");
  725.     
  726.     theWindow = GetNextWindowBehind (theWindow);
  727.     while (theWindow)
  728.     {
  729.         DebugStr (*((WindowPeek)(*theWindow)->theWindow)->titleHandle);
  730.         theWindow = GetNextWindowBehind (theWindow);
  731.     }
  732.     
  733.     DebugStr ("\p-- END OF LIST --;g");
  734. }
  735.